import os

from utils import date_util, k_util, ave_util, excel_util, json_util, read_config

today_str = date_util.get_format_date_str("%Y-%m-%d")
base_result_path = os.path.join(read_config.data_path, 'result', '突破均线', today_str, '历史验证数据')
result_file_name = '验证结果'
view_file_path = os.path.join(base_result_path, '验证')

if not os.path.exists(view_file_path):
    os.makedirs(view_file_path)  # 没有创建文件夹

up_fd = 1  # 突破幅度百分比 * 10000
down_fd = 1  # 突破幅度百分比 * 10000


# list_s : 股票列表
# size : 要验证的股票交易日天数
def monitor_up_down(list_s, size):
    for stock_info in list_s:
        capital_pool = 1000000  # 十万的初始资金
        position_money = 0  # 持仓金额
        hand_num = 0  # 持有多少手股票
        code = stock_info['code']  # 股票编码
        name = stock_info['name']  # 股票名称
        content_arr = [['编码', '名称', '日期', '成交价', '买卖', '持有股', '变更资金', '总资本', '间隔天数']]  # 生成的excel标题行
        k_lines = k_util.day_k_local(code, size + 5)  # 获取比size多五日的k线数据 k_util 可以在代码中获取
        k_lines.reverse()
        size = len(k_lines)  # 重新定义size防止新股票不够用
        k_lines_n = k_lines[0:5]
        pointer = 0  # k_lines_n的替换指针
        ave_price = ave_util.ave_line_price(k_lines_n, 5)
        sp4 = float(json_util.info_to_json(k_lines_n[4])['sp'])
        up_down_flag = 0  # 0:需要突破 1:监控跌破
        if sp4 > ave_price: up_down_flag = 1
        for num in range(size - 5):
            ave_price = ave_util.ave_line_price(k_lines_n, 5)
            pointer_v1 = pointer + 4  # k_lines_n 上一天的参数
            if pointer_v1 > 4:
                pointer_v1 = pointer_v1 - 5
            spp = float(json_util.info_to_json(k_lines_n[pointer_v1])['sp'])  # 上一天的收盘价
            kf5 = json_util.info_to_json(k_lines[num + 5])  # 最新一天k
            k_lines_n[pointer] = kf5
            if pointer == 4:
                pointer = 0
            else:
                pointer += 1
            max5 = float(kf5['max'])  # 次日的最高价
            min5 = float(kf5['min'])  # 次日的最低价
            kp5 = float(kf5['kp'])  # 次日的开盘价
            rq5 = kf5['rq']  # 次日的日期yyyy-MM-dd
            if up_down_flag == 0:  # 0:需要突破5日均线
                # 有效突破五日均线 准备买入
                if (max5 - ave_price) / spp * 10000 > up_fd:
                    # 空仓天数
                    interval_days = 0
                    length = len(content_arr)
                    if length != 1:
                        time_str = content_arr[length - 1][2]
                        interval_days = date_util.diff_days_str(time_str, rq5)
                    # 买入价格
                    buy_price = ave_price + ave_price * up_fd / 10000
                    if min5 > buy_price:
                        print(name + '当天' + rq5 + '高开高走')
                        buy_price = float(kp5)
                    hand_num = int((capital_pool - position_money) / buy_price / 100)
                    if hand_num == 0: continue
                    position_money = hand_num * buy_price * 100  # 持仓资金
                    capital_pool = capital_pool - position_money - position_money * 0.00025  # 总资产
                    up_down_flag = 1  # 变更flag
                    row_arr = [code, name, rq5, buy_price, 1, hand_num * 100, position_money,
                               capital_pool + position_money, interval_days]
                    content_arr.append(row_arr)
            elif up_down_flag == 1:  # 1:需要突破5日均线
                if (ave_price - min5) / spp * 10000 > down_fd:
                    # 持仓天数
                    interval_days = 0
                    length = len(content_arr)
                    if length != 1:
                        time_str = content_arr[length - 1][2]
                        interval_days = date_util.diff_days_str(time_str, rq5)
                    # 卖出价格
                    sell_price = ave_price - ave_price * down_fd / 10000
                    if sell_price > kp5:  # 当收盘价大于 当日最高价时
                        print(name + '当天' + rq5 + '暴跌以开盘价卖出')
                        sell_price = kp5
                    if hand_num == 0:
                        up_down_flag = 0
                        continue
                    position_money = hand_num * sell_price * 100  # 减仓资金
                    capital_pool = capital_pool + position_money - position_money * 0.00025
                    up_down_flag = 0  # 变更flag
                    row_arr = [code, name, rq5, sell_price, -1, 0, position_money, capital_pool, interval_days]
                    position_money = 0  # 重置参数
                    hand_num = 0  # 重置参数
                    content_arr.append(row_arr)
        if len(content_arr) > 1:
            content_arr = deal_excel_result(content_arr)
            excel_util.gen_an_excel(view_file_path, name + code, '', content_arr)


# 汇总操作结果
def deal_excel_result(content):
    # content_arr = [['0编码', '1名称', '2日期', '3成交价', '4买卖', '5持有股', '6变更资金', '7总资本', '8间隔天数']]  # 生成的excel标题行
    size = len(content)
    content_beg = content[1]
    content_end = content[size - 1]
    end_price = content_end[3]
    beg_price = content_beg[3]
    end_capital = content_end[7]
    beg_date = content_beg[2]
    end_date = content_end[2]
    days = date_util.diff_days_str(content_beg[2], content_end[2])  # 总操作天数
    amt_incr = round((end_price - beg_price) / beg_price * 100, 2)  # 价格涨幅( %)    91.56
    earnings_incr = round((end_capital - 1000000) / 10000, 2)  # 盈利涨幅( %)    91.56
    days_hold_all = 0  # 持仓天数
    for i in range(1, size):
        row = content[i]
        bs = row[4]
        if bs == -1:
            days_hold_all += row[8]
    content.append([])
    content.append(['', '', '', '名称', content_end[1]])
    content.append(['', '', '', '总操作天数', days])
    content.append(['', '', '', '开始日期', beg_date])
    content.append(['', '', '', '结束日期', end_date])
    content.append(['', '', '', '全仓天数', days_hold_all])
    content.append(['', '', '', '半仓天数', 0])
    content.append(['', '', '', '空仓天数', days - days_hold_all])
    content.append(['', '', '', '价格涨幅( %)', amt_incr])
    content.append(['', '', '', '盈利涨幅( %)', earnings_incr])
    content.append(['', '', '', '操作次数', size - 1])
    return content


if __name__ == '__main__':
    stock_list = [
        {'code': '600660', 'name': '福耀玻璃'},
        {'code': '600859', 'name': '王府井'},
        {'code': '601318', 'name': '中国平安'}
    ]
    monitor_up_down(stock_list, 120)
